home *** CD-ROM | disk | FTP | other *** search
/ Scene Storm / Scene Storm - Volume 1.iso / coding / c / tinyterm / tt.c < prev    next >
C/C++ Source or Header  |  1995-11-16  |  27KB  |  1,049 lines

  1. #define QUIT        1
  2. #define DOWNLOAD    2
  3. #define UPLOAD      3
  4.  
  5. struct GfxBase *GfxBase = NULL;
  6. struct DiskFontBase *DiskfontBase = NULL;
  7.  
  8. struct Device *ConsoleDevice = NULL;
  9. struct Library *XProtocolBase = NULL;
  10. struct XPR_IO *XIO = NULL;
  11. LONG XPRFlags = 0;
  12.  
  13. APTR OldWindowPtr;
  14.  
  15. BPTR filein;
  16. BPTR fileout;
  17. LONG confh;
  18. struct StandardPacket *MyPacket = NULL;
  19.  
  20. struct MsgPort *ConPort;
  21. struct MsgPort *ConSink = NULL;
  22. struct MsgPort *SerSink = NULL;
  23. struct MsgPort *TimerSink = NULL;
  24. struct IOExtSer IOsr;
  25. struct IOExtSer IOsw;
  26. struct IOExtSer IOss;
  27. struct IOStdReq IOcr;
  28. struct timerequest IOtr;
  29. LONG ConSig;
  30. LONG SerSig;
  31. LONG TimerSig;
  32.  
  33. struct KeyMap *Keymap = NULL;
  34. struct InputEvent RKE = {
  35.     NULL,
  36.     IECLASS_RAWKEY,
  37.     0,
  38.     0,
  39.     0
  40. };
  41.  
  42. char *SerInBuf = NULL;
  43. char *SerOutBuf;
  44. char ConInBuf[64];
  45. char CSBuf[64];
  46. char Init[256];
  47.  
  48. WORD CSState = 0;
  49. WORD CSPos = 0;
  50.  
  51. char *DeviceName = "serial.device";
  52. LONG DeviceUnit = 0;
  53. char *Protocol = NULL;
  54. char *KeymapName = NULL;
  55. char *FontName = NULL;
  56. char *XferDir = NULL;
  57.  
  58. struct TextFont *Font = NULL;
  59. struct TextFont *OldFont = NULL;
  60.  
  61. WORD IOswIP;
  62. WORD IOsrIP;
  63. WORD PIP;
  64. WORD TIP;
  65.  
  66. LONG dectoint(REGISTER char *str)
  67. {
  68.     REGISTER long val = 0;
  69.     REGISTER char c;
  70.     while ((c = *str) >= '0' && c <= '9') {
  71.         val = (((val<<2)+val)<<1) + c-'0';
  72.         str++;
  73.     }
  74.     return(val);
  75. }
  76.  
  77. char *inttodec(LONG num, char *buf, WORD width)
  78. {
  79.     REGISTER WORD i;
  80.     for (i = 0; i < width; i++) {
  81.         buf[i] = ' ';
  82.     }
  83.     buf[width - 1] = '0';
  84.     buf[width] = '\0';
  85.     i = width;
  86.     while (num && --i >= 0) {
  87.         buf[i] = '0' + (num % 10);
  88.         num /= 10;
  89.     }
  90.     return buf;
  91. }
  92.  
  93. char *strlwr(str)
  94. char *str;
  95. {
  96.     REGISTER char *p = str;
  97.     REGISTER char c;
  98.  
  99.     while (c = *p) {
  100.         if ('A' <= c && c <= 'Z') {
  101.             *p = c + ('a' - 'A');
  102.         }
  103.         ++p;
  104.     }
  105.     return str;
  106. }
  107.  
  108. LONG SendPacket(struct MsgPort *port,
  109.                 struct MsgPort *replyport,
  110.                 LONG type,
  111.                 LONG arg1, LONG arg2, LONG arg3, LONG arg4,
  112.                 LONG arg5, LONG arg6, LONG arg7)
  113. {
  114.     struct StandardPacket *Packet;
  115.     struct MsgPort *rport = replyport;
  116.  
  117.     Packet = AllocMem(sizeof(struct StandardPacket), MEMF_PUBLIC|MEMF_CLEAR);
  118.     if (!Packet) {
  119.         return -1L;
  120.     }
  121.  
  122.     if (!replyport) {
  123.         rport = CreatePort(0L, 0L);
  124.         if (!rport) {
  125.             FreeMem(Packet, sizeof(struct StandardPacket));
  126.             return -1L;
  127.         }
  128.     }
  129.     Packet->sp_Msg.mn_Node.ln_Type = NT_MESSAGE;
  130.     Packet->sp_Msg.mn_Node.ln_Name = (char *)&(Packet->sp_Pkt);
  131.     Packet->sp_Msg.mn_ReplyPort = rport;
  132.     Packet->sp_Pkt.dp_Link = &Packet->sp_Msg;
  133.     Packet->sp_Pkt.dp_Port = rport;
  134.     Packet->sp_Pkt.dp_Type = type;
  135.     Packet->sp_Pkt.dp_Arg1 = arg1;
  136.     Packet->sp_Pkt.dp_Arg2 = arg2;
  137.     Packet->sp_Pkt.dp_Arg3 = arg3;
  138.     Packet->sp_Pkt.dp_Arg4 = arg4;
  139.     Packet->sp_Pkt.dp_Arg5 = arg5;
  140.     Packet->sp_Pkt.dp_Arg6 = arg6;
  141.     Packet->sp_Pkt.dp_Arg7 = arg7;
  142.     PutMsg(port, (struct Message *)Packet);
  143.     if (!replyport) {
  144.         LONG result;
  145.  
  146.         do {
  147.             WaitPort(rport);
  148.         } while (!GetMsg(rport));
  149.         DeletePort(rport);
  150.         result = Packet->sp_Pkt.dp_Res1;
  151.         FreeMem(Packet, sizeof(struct StandardPacket));
  152.         return result;
  153.     } else {
  154.         return (LONG)Packet;
  155.     }
  156. }
  157.  
  158. VOID QueueCon()
  159. {
  160.     if (!PIP) {
  161.         SendPacket(ConPort, ConSink, ACTION_READ,
  162.           confh, (LONG)ConInBuf, 64, 0, 0, 0, 0);
  163.         PIP = TRUE;
  164.     }
  165. }
  166.  
  167. WORD CheckCon()
  168. {
  169.     WORD chars = -1;
  170.     struct StandardPacket *p;
  171.  
  172.     if (p = (struct StandardPacket *)GetMsg(ConSink)) {
  173.         PIP = FALSE;
  174.         chars = p->sp_Pkt.dp_Res1;
  175.         FreeMem(p, sizeof(struct StandardPacket));
  176.     }
  177.     return chars;
  178. }
  179.  
  180. LONG QueueTimer(LONG micros)
  181. {
  182.     LONG timeout = micros;
  183.  
  184.     if (!TIP) {
  185.         if (!timeout) {
  186.             return 0;
  187.         }
  188.         if (micros > 3000000) {
  189.             timeout = 3000000;
  190.         }
  191.         IOtr.tr_time.tv_secs  = timeout / 1000000;
  192.         IOtr.tr_time.tv_micro = timeout % 1000000;
  193.         SendIO((struct IORequest *)&IOtr);
  194.         TIP = TRUE;
  195.         return micros - timeout;
  196.     }
  197. }
  198.  
  199. VOID AbortRequest(WORD *InProgress, struct IORequest *IOR)
  200. {
  201.     if (*InProgress) {
  202.         AbortIO(IOR);
  203.         WaitIO(IOR);
  204.         *InProgress = FALSE;
  205.     }
  206. }
  207.  
  208. #define AbortTimer()    AbortRequest(&TIP, (struct IORequest *)&IOtr)
  209. #define AbortSerRead()  AbortRequest(&IOsrIP, (struct IORequest *)&IOsr)
  210. #define AbortSerWrite() AbortRequest(&IOsrIP, (struct IORequest *)&IOsr)
  211.  
  212. WORD FinishedIO(WORD *InProgress, struct IORequest *IOR)
  213. {
  214.     if (*InProgress && CheckIO(IOR)) {
  215.         WaitIO(IOR);
  216.         *InProgress = FALSE;
  217.         return TRUE;
  218.     } else {
  219.         return FALSE;
  220.     }
  221. }
  222.  
  223. #define FinishedTimer()     FinishedIO(&TIP, (struct IORequest *)&IOtr)
  224. #define FinishedSerRead()   FinishedIO(&IOsrIP, (struct IORequest *)&IOsr)
  225. #define FinishedSerWrite()  FinishedIO(&IOswIP, (struct IORequest *)&IOsw)
  226.  
  227. QueueSerRead(char *buff, LONG length)
  228. {
  229.     if (!IOsrIP) {
  230.         IOsr.IOSer.io_Command = CMD_READ;
  231.         IOsr.IOSer.io_Length = length;
  232.         IOsr.IOSer.io_Data = (APTR)buff;
  233.         SendIO((struct IORequest *)&IOsr);
  234.         IOsrIP = TRUE;
  235.     }
  236. }
  237.  
  238. LONG SerRead(char *buff, LONG length, LONG micros)
  239. {
  240.     LONG pos = 0;
  241.     WORD n;
  242.     WORD carrier;
  243.  
  244.     if (!buff) {
  245.         return -1;
  246.     }
  247.  
  248.     micros = QueueTimer(micros);
  249.  
  250.     for (;;) {
  251.         if (!IOsrIP) {
  252.             IOss.IOSer.io_Command = SDCMD_QUERY;
  253.             DoIO((struct IORequest *)&IOss);
  254.             carrier = (IOss.io_Status & CIAF_COMCD) ? 0 : 1;
  255.             if (n = IOss.IOSer.io_Actual) {
  256.                 IOsr.IOSer.io_Command = CMD_READ;
  257.                 IOsr.IOSer.io_Length = min(n, length);
  258.                 IOsr.IOSer.io_Data = (APTR)&buff[pos];
  259.                 DoIO((struct IORequest *)&IOsr);
  260.                 pos += IOsr.IOSer.io_Actual;
  261.                 length -= IOsr.IOSer.io_Actual;
  262.             }
  263.         }
  264.         if (length == 0 || !TIP) {
  265.             AbortTimer();
  266.             return pos;
  267.         }
  268.         if (FinishedTimer()) {
  269.             if (micros) {
  270.                 micros = QueueTimer(micros);
  271.             } else {
  272.                 AbortSerRead();
  273.                 return pos;
  274.             }
  275.         }
  276.         if (!carrier) {
  277.             AbortTimer();
  278.             AbortSerRead();
  279.             return -1;
  280.         }
  281.         QueueSerRead((char *)&buff[pos], length);
  282.         if (Wait(TimerSig | SerSig) & SerSig) {
  283.             if (FinishedSerRead()) {
  284.                 pos += IOsr.IOSer.io_Actual;
  285.                 length -= IOsr.IOSer.io_Actual;
  286.             }
  287.         }
  288.     }
  289. }
  290.  
  291. VOID SerWrite(char *str, LONG n)
  292. {
  293.     LONG temp = n;
  294.     char t[10];
  295.  
  296.     while (n) {
  297.         if (IOswIP) {
  298.             WaitIO((struct IORequest *)&IOsw);
  299.             IOswIP = FALSE;
  300.         }
  301.         temp = min(n, 256);
  302.         CopyMem(str, SerOutBuf, temp);
  303.         IOsw.IOSer.io_Command = CMD_WRITE;
  304.         IOsw.IOSer.io_Length = temp;
  305.         IOsw.IOSer.io_Data = (APTR)SerOutBuf;
  306.         SendIO((struct IORequest *)&IOsw);
  307.         IOswIP = TRUE;
  308.         n -= temp;
  309.     }
  310. }
  311.  
  312. VOID SerFlush()
  313. {
  314.     IOss.IOSer.io_Command = CMD_FLUSH;
  315.     DoIO((struct IORequest *)&IOss);
  316. }
  317.  
  318. CloseStuff()
  319. {
  320.     if (SerInBuf)               FreeMem(SerInBuf, 512);
  321.     if (IOsw.IOSer.io_Message.mn_ReplyPort) {
  322.         DeletePort(IOsw.IOSer.io_Message.mn_ReplyPort);
  323.     }
  324.     if (IOsr.IOSer.io_Device)   CloseDevice((struct IORequest *)&IOsr);
  325.     if (IOtr.tr_node.io_Device) CloseDevice((struct IORequest *)&IOtr);
  326.     if (IOcr.io_Device)         CloseDevice((struct IORequest *)&IOcr);
  327.     if (ConSink)                DeletePort(ConSink);
  328.     if (SerSink)                DeletePort(SerSink);
  329.     if (TimerSink)              DeletePort(TimerSink);
  330.     if (Font)                   CloseFont(Font);
  331.     if (DiskfontBase)           CloseLibrary((struct Library *)DiskfontBase);
  332.     if (GfxBase)                CloseLibrary((struct Library *)GfxBase);
  333.     ((struct Process *)FindTask(NULL))->pr_WindowPtr = OldWindowPtr;
  334.     exit(0);
  335. }
  336.  
  337. struct TextFont *SmartOpenFont(ta)
  338. struct TextAttr *ta;
  339. {
  340.     struct TextFont *MemF;
  341.     struct TextFont *DskF = NULL;
  342.  
  343.     if ((MemF = OpenFont(ta)) && ta->ta_YSize == MemF->tf_YSize) {
  344.         return MemF;
  345.     }
  346.  
  347.     if (DiskfontBase) {
  348.         DskF = OpenDiskFont(ta);
  349.     }
  350.  
  351.     if (!MemF) {
  352.         return DskF;
  353.     }
  354.     if (!DskF) {
  355.         return MemF;
  356.     }
  357.     if (abs(ta->ta_YSize - MemF->tf_YSize) <=
  358.         abs(ta->ta_YSize - DskF->tf_YSize)) {
  359.         CloseFont(DskF);
  360.         return MemF;
  361.     }
  362.     CloseFont(MemF);
  363.     return DskF;
  364. }
  365.  
  366. OpenStuff()
  367. {
  368.     OldWindowPtr = ((struct Process *)FindTask(NULL))->pr_WindowPtr;
  369.     ((struct Process *)FindTask(NULL))->pr_WindowPtr = (APTR)-1;
  370.     IOsr.IOSer.io_Device = NULL;
  371.     IOsw.IOSer.io_Message.mn_ReplyPort = NULL;
  372.     IOtr.tr_node.io_Device = NULL;
  373.     IOcr.io_Device = NULL;
  374.  
  375.     GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0);
  376.     if (!GfxBase) {
  377.         Write(fileout, "Can't open graphics.library.\n", 29);
  378.         CloseStuff();
  379.     }
  380.  
  381.     if (FontName) {
  382.         struct TextAttr ta;
  383.         char temp[33];
  384.         WORD pos = 0;
  385.  
  386.         DiskfontBase = (struct DiskFontBase *)OpenLibrary("diskfont.library", 0);
  387.         strcpy(temp, FontName);
  388.         ta.ta_Name = (UBYTE *)temp;
  389.         while (temp[pos] && temp[pos] != '/') {
  390.             ++pos;
  391.         }
  392.         if (temp[pos] == '\0') {     /* No size */
  393.             ta.ta_YSize = 8;
  394.         } else {
  395.             temp[pos] = '\0';
  396.             ta.ta_YSize = dectoint(&temp[pos + 1]);
  397.         }
  398.         if (pos > 5) {
  399.             (VOID)strlwr(&temp[pos - 5]);
  400.             if (strcmp(&temp[pos - 5], ".font")) {
  401.                 strcpy(&temp[pos], ".font");
  402.             }
  403.         } else {
  404.             strcpy(&temp[pos], ".font");
  405.         }
  406.         ta.ta_Style = 0;
  407.         ta.ta_Flags = 0;
  408.         Font = SmartOpenFont(&ta);
  409.         if (!Font) {
  410.             Write(fileout, "Can't open font.\n", 17);
  411.         }
  412.     }
  413.  
  414.     if (!(ConSink = CreatePort(0, 0))) {
  415.         Write(fileout, "Can't open console port.\n", 25);
  416.         CloseStuff();
  417.     }
  418.     if (!(SerSink = CreatePort(0, 0))) {
  419.         Write(fileout, "Can't open serial read port.\n", 29);
  420.         CloseStuff();
  421.     }
  422.     if (!(TimerSink = CreatePort(0, 0))) {
  423.         Write(fileout, "Can't open timer port.\n", 23);
  424.         CloseStuff();
  425.     }
  426.     ConSig = 1L << ConSink->mp_SigBit;
  427.     SerSig = 1L << SerSink->mp_SigBit;
  428.     TimerSig = 1L << TimerSink->mp_SigBit;
  429.  
  430.     IOsr.io_SerFlags = SERF_SHARED | SERF_XDISABLED;
  431.     IOsr.IOSer.io_Message.mn_ReplyPort = SerSink;
  432.  
  433.     if (OpenDevice(DeviceName, DeviceUnit, (struct IORequest *)&IOsr, NULL)) {
  434.         IOsr.IOSer.io_Device = NULL;
  435.         Write(fileout, "Can't open serial port for read.\n", 33);
  436.         CloseStuff();
  437.     }
  438.  
  439.     /*
  440.      *        Assume a Getty is running, if the opencount is > 2 then
  441.      *        assume collision and disallow
  442.      */
  443.  
  444.     if (IOsr.IOSer.io_Device->dd_Library.lib_OpenCnt > 2) {
  445.         Write(fileout, "Collision, serial port in use!\n", 31);
  446.         CloseStuff();
  447.     }
  448.  
  449.     CopyMem((char *)&IOsr, (char *)&IOsw, sizeof(struct IOExtSer));
  450.     IOsw.IOSer.io_Message.mn_ReplyPort = CreatePort(0, 0);
  451.     if (!IOsw.IOSer.io_Message.mn_ReplyPort) {
  452.         Write(fileout, "Can't open serial write port.\n", 30);
  453.         CloseStuff();
  454.     }
  455.     CopyMem((char *)&IOsw, (char *)&IOss, sizeof(struct IOExtSer));
  456.  
  457.     SerInBuf = AllocMem(512, MEMF_PUBLIC | MEMF_CLEAR);
  458.     if (!SerInBuf) {
  459.         Write(fileout, "No memory for serial buffers.\n", 30);
  460.         CloseStuff();
  461.     }
  462.     SerOutBuf = &SerInBuf[256];
  463.  
  464.     if (OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)&IOtr, 0))  {
  465.         Write(fileout, "Can't open timer device.\n", 25);
  466.         CloseStuff();
  467.     }
  468.  
  469.     IOtr.tr_node.io_Message.mn_ReplyPort = TimerSink;
  470.     IOtr.tr_node.io_Command = TR_ADDREQUEST;
  471.     IOtr.tr_node.io_Error = 0;
  472.  
  473.     if (OpenDevice("console.device", -1L, (struct IORequest *)&IOcr, NULL)) {
  474.         Write(fileout, "Can't open console device.\n", 27);
  475.         CloseStuff();
  476.     }
  477.     ConsoleDevice = IOcr.io_Device;
  478. }
  479.  
  480. VOID RawCon()
  481. {
  482.     if (!filein) {
  483.         filein = Open("*", MODE_OLDFILE);
  484.         ConPort = ((struct FileHandle *)BADDR(filein))->fh_Type;
  485.         confh = ((struct FileHandle *)BADDR(filein))->fh_Arg1;
  486.         SendPacket(ConPort, NULL, ACTION_SCREEN_MODE, RAW, 0, 0, 0, 0, 0, 0);
  487.         Write(fileout, "\2331{", 3);
  488.     }
  489. }
  490.  
  491. VOID StdCon()
  492. {
  493.     if (filein) {
  494.         Write(fileout, "\2331}", 3);
  495.         SendPacket(ConPort, NULL, ACTION_SCREEN_MODE, COOKED, 0, 0, 0, 0, 0, 0);
  496.         Close(filein);
  497.         filein = NULL;
  498.         if (PIP) {
  499.             WaitPort(ConSink);
  500.             MyPacket = (struct StandardPacket *)GetMsg(ConSink);
  501.             FreeMem(MyPacket, sizeof(struct StandardPacket));
  502.         }
  503.     }
  504. }
  505.  
  506.  
  507. VOID tt_update(struct XPR_UPDATE *x)
  508. {
  509.     char temp[10];
  510.     STATIC char msg[51];
  511.     STATIC char filename[51];
  512.     STATIC LONG bytes;
  513.     LONG update;
  514.  
  515.     int_start();
  516.  
  517.     update = x->xpru_updatemask;
  518.     if (update & XPRU_MSG)       strncpy(msg, x->xpru_msg, 50);
  519.     if (update & XPRU_ERRORMSG)  strncpy(msg, x->xpru_errormsg, 50);
  520.     if (update & XPRU_FILENAME)  strncpy(filename, x->xpru_filename, 50);
  521.     if (update & XPRU_BYTES)     bytes = x->xpru_bytes;
  522.     Write(fileout, msg, strlen(msg));
  523.     Write(fileout, "\233K\n", 3);
  524.     Write(fileout, filename, strlen(filename));
  525.     Write(fileout, "\233K\nBytes: ", 10);
  526.     Write(fileout, inttodec(bytes, temp, 7), 7);
  527.     Write(fileout, "\n", 1);
  528.     if (update & (XPRU_EXPECTTIME | XPRU_ELAPSEDTIME)) {
  529.         Write(fileout, "Expected time: ", 15);
  530.         Write(fileout, x->xpru_expecttime, strlen(x->xpru_expecttime));
  531.         Write(fileout, "  Elapsed time: ", 16);
  532.         Write(fileout, x->xpru_elapsedtime, strlen(x->xpru_elapsedtime));
  533.     }
  534.     Write(fileout, "\r\2333A", 4);
  535.     int_end();
  536. }
  537.  
  538. LONG tt_gets(char *prompt, char *buffer)
  539. {
  540.     LONG length;
  541.     int_start();
  542.     StdCon();
  543.     Write(fileout, prompt, strlen(prompt));
  544.     length = Read(Input(), buffer, 256);
  545.     if (length > 0) {
  546.         buffer[length - 1] = '\0';
  547.     }
  548.     RawCon();
  549.     int_end();
  550.     return 0;
  551. }
  552.  
  553. LONG tt_swrite(char *s, LONG n)
  554. {
  555.     char temp[10];
  556.     int_start();
  557.     SerWrite(s, n);
  558.     int_end();
  559.     return 0;
  560. }
  561.  
  562. LONG tt_sread(char *buff, LONG length, LONG micros)
  563. {
  564.     LONG result;
  565.     int_start();
  566.     result = SerRead(buff, length, micros);
  567.     int_end();
  568.     return result;
  569. }
  570.  
  571. LONG tt_sflush()
  572. {
  573.     int_start();
  574.     SerFlush();
  575.     while (SerRead(SerInBuf, 256, 0));  /* Clear serial buffer */
  576.     int_end();
  577. }
  578.  
  579. VOID *tt_fopen(s, t)
  580. char *s, *t;
  581. {
  582.     BPTR file = NULL;
  583.     int_start();
  584.     switch (*t) {
  585.         case 'r':
  586.             file = Open(s, MODE_OLDFILE);
  587.             break;
  588.         case 'w':
  589.             file = Open(s, MODE_NEWFILE);
  590.             break;
  591.         case 'a':
  592.             file = Open(s, MODE_OLDFILE);
  593.             if (!file) {
  594.                 file = Open(s, MODE_NEWFILE);
  595.             }
  596.             if (file) {
  597.                 Seek(file, 0, OFFSET_END);
  598.             }
  599.             break;
  600.     }
  601.     int_end();
  602.     return (VOID *)file;
  603. }
  604.  
  605. VOID tt_fclose(VOID *fp)
  606. {
  607.     int_start();
  608.     Close((BPTR)fp);
  609.     int_end();
  610. }
  611.  
  612. LONG tt_fread(char *buff, LONG size, LONG count, VOID *fp)
  613. {
  614.     LONG result;
  615.     int_start();
  616.     result = Read((BPTR)fp, buff, size * count);
  617.     if (result == -1) {
  618.         result = 0;
  619.     }
  620.     result /= size;
  621.     int_end();
  622.     return result;
  623. }
  624.  
  625. LONG tt_fwrite(char *buff, LONG size, LONG count, VOID *fp)
  626. {
  627.     LONG result;
  628.     int_start();
  629.     result = Write((BPTR)fp, buff, size * count);
  630.     if (result == -1) {
  631.         result = 0;
  632.     }
  633.     result /= size;
  634.     int_end();
  635.     return result;
  636. }
  637.  
  638. LONG seekmode[3] = {
  639.     OFFSET_BEGINNING,
  640.     OFFSET_CURRENT,
  641.     OFFSET_END
  642. };
  643.  
  644. LONG tt_fseek(VOID *fp, LONG offset, LONG origin)
  645. {
  646.     int_start();
  647.     Seek((BPTR)fp, offset, seekmode[origin]);
  648.     int_end();
  649.     return 0;
  650. }
  651.  
  652. LONG tt_chkabort()
  653. {
  654.     LONG abort = 0;
  655.     WORD n;
  656.     int_start();
  657.     if ((n = CheckCon()) != -1) {
  658.         WORD i;
  659.         for (i = 0; i < n; i++) {
  660.             if (ConInBuf[i] == 27) {
  661.                 abort = 1;
  662.                 break;
  663.             }
  664.         }
  665.         if (!abort) {
  666.             QueueCon();
  667.         }
  668.     }
  669.     int_end();
  670.     return abort;
  671. }
  672.  
  673. LONG tt_finfo(char *filename, LONG infotype)
  674. {
  675.     LONG result = 0;
  676.  
  677.     int_start();
  678.     if (infotype == 1) {
  679.         BPTR lock;
  680.         struct FileInfoBlock *fib;
  681.         if (lock = Lock(filename, ACCESS_READ)) {
  682.             if (fib = AllocMem(sizeof(struct FileInfoBlock), MEMF_PUBLIC)) {
  683.                 if (Examine(lock, (BPTR)fib)) {
  684.                     result = fib->fib_Size;
  685.                 }
  686.                 FreeMem(fib, sizeof(struct FileInfoBlock));
  687.             }
  688.             UnLock(lock);
  689.         }
  690.     } else if (infotype == 2) {
  691.         result = 1;   /* Always binary */
  692.     }
  693.     int_end();
  694.     return result;
  695. }
  696.  
  697. xpr_setup(struct XPR_IO *IO)
  698. {
  699.    IO->xpr_filename  = NULL;
  700.    IO->xpr_fopen     = tt_fopen;
  701.    IO->xpr_fclose    = tt_fclose;
  702.    IO->xpr_fread     = tt_fread;
  703.    IO->xpr_fwrite    = tt_fwrite;
  704.    IO->xpr_sread     = tt_sread;
  705.    IO->xpr_swrite    = tt_swrite;
  706.    IO->xpr_sflush    = tt_sflush;
  707.    IO->xpr_update    = tt_update;
  708.    IO->xpr_chkabort  = tt_chkabort;
  709.    IO->xpr_chkmisc   = NULL;
  710.    IO->xpr_gets      = tt_gets;
  711.    IO->xpr_setserial = NULL;
  712.    IO->xpr_ffirst    = NULL;
  713.    IO->xpr_fnext     = NULL;
  714.    IO->xpr_finfo     = tt_finfo;
  715.    IO->xpr_fseek     = tt_fseek;
  716.    IO->xpr_extension = 0L;
  717.    IO->xpr_options   = NULL;
  718.    IO->xpr_data      = NULL;
  719.  
  720.    return;
  721. }
  722.  
  723. WORD DoKeys(WORD n)
  724. {
  725.     WORD i;
  726.     WORD chars = 0;
  727.  
  728.     for (i = 0; i < n; i++) {
  729.         unsigned char ch = ConInBuf[i];
  730.         if (CSState == 1) {
  731.             if (ch == '[') {
  732.                 CSState = 2;
  733.             } else {
  734.                 CSState = -2;
  735.             }
  736.         }
  737.         if (ch == 0x9B) {
  738.             CSState = 2;
  739.         }
  740.         if (ch == 0x1B) {
  741.             CSState = 1;
  742.         }
  743.         if ((CSState == 3) && ((ch >= 0x40) && (ch <= 0x7E))) {
  744.             CSState = -1;
  745.             if (ch == '|') {    /* Raw Key Event */
  746.                 REGISTER char *p;
  747.                 LONG temp;
  748.                 CSBuf[CSPos] = 0;
  749.                 CSPos = 0;
  750.                 p = CSBuf;
  751.                 RKE.ie_Class = dectoint(p);     while (*p++ != ';');
  752.                 RKE.ie_SubClass = dectoint(p);  while (*p++ != ';');
  753.                 RKE.ie_Code = dectoint(p);      while (*p++ != ';');
  754.                 RKE.ie_Qualifier = dectoint(p); while (*p++ != ';');
  755.                 temp = dectoint(p) << 16;       while (*p++ != ';');
  756.                 temp |= dectoint(p);
  757.                 RKE.ie_EventAddress = (APTR)temp;
  758.                 temp = RawKeyConvert(&RKE, &ConInBuf[chars], 64 - chars, Keymap);
  759.                   /* If it's a command key, dump all other chars, put
  760.                      the command key in position 0 and return -1 */
  761.                 if (temp == 1 && RKE.ie_Qualifier & IEQUALIFIER_RCOMMAND) {
  762.                     ConInBuf[0] = ConInBuf[chars];
  763.                     return -1;
  764.                 }
  765.                 chars += temp;
  766.             }
  767.         }
  768.         if (CSState == 3) {
  769.             CSBuf[CSPos++] = ch;
  770.         }
  771.         if (CSState == 2) {
  772.             CSState = 3;
  773.             CSPos = 0;
  774.         }
  775.     }
  776.     return chars;
  777. }
  778.  
  779. VOID CloseProtocol()
  780. {
  781.     if (XIO) {
  782.         XProtocolCleanup(XIO);
  783.         XPRFlags = 0;
  784.         FreeMem(XIO, sizeof(struct XPR_IO));
  785.     }
  786.     if (XProtocolBase)          CloseLibrary(XProtocolBase);
  787. }
  788.  
  789. char *InitProtocol(char *protocol)
  790. {
  791.     char options[256];
  792.     char temp[64];
  793.     BPTR envfile;
  794.  
  795.     options[0] = '\0';
  796.     strcpy(temp, "ENV:xpr");
  797.     strcat(temp, protocol);
  798.     if (envfile = Open(temp, MODE_OLDFILE)) {
  799.         LONG length;
  800.         length = Read(envfile, options, sizeof(options));
  801.         if (length == -1) {
  802.             options[0] = '\0';
  803.         } else {
  804.             REGISTER WORD i = 0;
  805.             while (i < length) {
  806.                 if (options[i] == '\n') {
  807.                     options[i] = '\0';
  808.                     length = i;
  809.                 }
  810.             }
  811.         }
  812.         Close(envfile);
  813.     }
  814.     strcpy(temp, "xpr");
  815.     strcat(temp, protocol);
  816.     strcat(temp, ".library");
  817.     XProtocolBase = OpenLibrary(temp, 0);
  818.     if (!XProtocolBase) {
  819.         Write(fileout, "Can't open protocol ", 20);
  820.         Write(fileout, protocol, strlen(protocol));
  821.         Write(fileout, ".\n", 2);
  822.         return NULL;
  823.     }
  824.     XIO = AllocMem(sizeof(struct XPR_IO), MEMF_PUBLIC | MEMF_CLEAR);
  825.     if (!XIO) {
  826.         return NULL;
  827.     }
  828.     xpr_setup(XIO);
  829.     XIO->xpr_filename = options;
  830.     XPRFlags = XProtocolSetup(XIO);
  831.     if (!(XPRFlags & XPRS_SUCCESS)) {
  832.         Write(fileout, "Can't open protocol ", 20);
  833.         Write(fileout, protocol, strlen(protocol));
  834.         Write(fileout, ".\n", 2);
  835.         CloseProtocol();
  836.         return NULL;
  837.     }
  838. }
  839.  
  840. struct KeyMap *FindKeymap(char *name)
  841. {
  842.     struct KeyMapResource *KMR;
  843.     KMR = (struct KeyMapResource *)OpenResource("keymap.resource");
  844.     if (KMR) {
  845.         struct KeyMapNode *KMN;
  846.         KMN = (struct KeyMapNode *)FindName(&KMR->kr_List, name);
  847.         if (!KMN) {
  848.             Write(fileout, "Keymap not loaded. Using default.\n", 34);
  849.         } else {
  850.             return &KMN->kn_KeyMap;
  851.         }
  852.     }
  853.     return NULL;
  854. }
  855.  
  856. struct TextFont *SetConFont(struct TextFont *Font)
  857. {
  858.     struct InfoData *id;
  859.     struct TextFont *oldfont;
  860.     struct Window *window;
  861.  
  862.     id = AllocMem(sizeof(struct InfoData), MEMF_PUBLIC | MEMF_CLEAR);
  863.     SendPacket(ConPort, NULL, ACTION_DISK_INFO,
  864.       C2B(id), 0, 0, 0, 0, 0, 0);
  865.     window = (struct Window *)id->id_VolumeNode;
  866.     oldfont = window->RPort->Font;
  867.     SetFont(window->RPort, Font);
  868.     Write(fileout, "\033c", 2);
  869.     return oldfont;
  870. }
  871.  
  872. VOID SelectProtocol()
  873. {
  874.     char protocol[256];
  875.  
  876.     tt_gets("Select protocol: ", protocol);
  877.     if (strlen(protocol)) {
  878.         CloseProtocol();
  879.         InitProtocol(protocol);
  880.     }
  881. }
  882.  
  883. VOID Transfer(WORD direction)
  884. {
  885.     char filename[256];
  886.  
  887.     if (XProtocolBase) {
  888.         tt_gets((direction ? "Download file: " : "Upload file: "), filename);
  889.         if (strlen(filename)) {
  890.             XIO->xpr_filename = filename;
  891.             Write(fileout, "-- ", 3);
  892.             Write(fileout, (direction ? "Download" : " Upload "), 8);
  893.             Write(fileout, " -- ESC to abort --\n\2330 p", 24);
  894.             QueueCon();
  895.             if (direction) {
  896.                 XProtocolReceive(XIO);
  897.             } else {
  898.                 XProtocolSend(XIO);
  899.             }
  900.             while (SerRead(SerInBuf, 256, 0));  /* Clear serial buffer */
  901.             Write(fileout, "\7\n\n\n\n\n\233 p", 9);
  902.         }
  903.     } else {
  904.         Write(fileout, "Transfer: No protocol selected.\n", 32);
  905.     }
  906. }
  907.  
  908. VOID _wb_parse() {}
  909. VOID _abort() {}
  910.  
  911. main(WORD argc, char **argv)
  912. {
  913.     BOOL go;
  914.     WORD eoa;
  915.     BPTR Home = NULL;
  916.  
  917.     fileout = Output();
  918.     strcpy(Init, "");
  919.     eoa = 0;
  920.     for (argc--, argv++; argc > 0; argc--, argv++) {
  921.         if (**argv == '-' && !eoa) { /* Argument coming up */
  922.             switch (*++(*argv)) {
  923.                 case 'S':       /* Serial device */
  924.                     if (ARGVAL()) DeviceName = *argv;
  925.                     break;
  926.                 case 'U':       /* Serial unit */
  927.                     if (ARGVAL()) DeviceUnit = dectoint(*argv);
  928.                     break;
  929.                 case 'P':       /* Protocol */
  930.                     if (ARGVAL()) Protocol = *argv;
  931.                     break;
  932.                 case 'K':       /* Keymap */
  933.                     if (ARGVAL()) KeymapName = *argv;
  934.                     break;
  935.                 case 'F':       /* Font */
  936.                     if (ARGVAL()) FontName = *argv;
  937.                     break;
  938.                 case 'D':       /* Transfer directory */
  939.                     if (ARGVAL()) XferDir = *argv;
  940.                     break;
  941.                 case '-':       /* End of args */
  942.                     eoa = 1;
  943.                     break;
  944.             }
  945.         } else if (!strcmp(*argv, "?")) {
  946.             Write(fileout,
  947.               "Usage: tt [-Sserial.device] [-Uunit] [-Pprotocol]\n"
  948.               "          [-Kkeymap] [-Ffont/size] [-Dxferdirectory]\n"
  949.               "          [modem startup text]\n", 134);
  950.             return(0);
  951.         } else {
  952.             strcat(Init, *argv);
  953.             strcat(Init, "\r");
  954.         }
  955.     }
  956.     OpenStuff();
  957.     RawCon();
  958.     if (Protocol) {
  959.         InitProtocol(Protocol);
  960.     }
  961.     if (KeymapName) {
  962.         Keymap = FindKeymap(KeymapName);
  963.     }
  964.     if (Font) {
  965.         OldFont = SetConFont(Font);
  966.     }
  967.     if (XferDir) {
  968.         BPTR temp = Lock(XferDir, ACCESS_READ);
  969.         if (!temp) {
  970.             Write(fileout, "Can't find transfer directory.\n", 31);
  971.         } else {
  972.             Home = CurrentDir((struct FileLock *)temp);
  973.         }    
  974.     }
  975.     IOswIP = FALSE;
  976.     IOsrIP = FALSE;
  977.     PIP = FALSE;
  978.     TIP = FALSE;
  979.  
  980.     while (SerRead(SerInBuf, 256, 0));  /* Clear serial buffer */
  981.  
  982.     SerWrite(Init, strlen(Init));
  983.  
  984.     QueueSerRead(SerInBuf, 1);
  985.     QueueCon();
  986.     go = TRUE;
  987.     while (go) {
  988.         WORD chars;
  989.         LONG signals;
  990.  
  991.         signals = Wait(ConSig | SerSig | SIGBREAKF_CTRL_C);
  992.         if (signals & SIGBREAKF_CTRL_C) {
  993.             go = FALSE;
  994.         }
  995.  
  996.         if ((chars = CheckCon()) != -1) {
  997.             chars = DoKeys(chars);
  998.             if (chars == -1) {
  999.                 switch (ConInBuf[0]) {
  1000.                     case 'q':
  1001.                         go = FALSE;
  1002.                         break;
  1003.                     case 'p':
  1004.                         SelectProtocol();
  1005.                         break;
  1006.                     case 'u':
  1007.                         Transfer(0);
  1008.                         break;
  1009.                     case 'd':
  1010.                         Transfer(1);
  1011.                         break;
  1012.                 }
  1013.             } else {
  1014.                 if (XPRFlags & XPRS_USERMON) {
  1015.                     chars = XProtocolUserMon(XIO, ConInBuf, chars, 64);
  1016.                 }
  1017.                 if (chars) {
  1018.                     SerWrite(ConInBuf, chars);
  1019.                 }
  1020.             }
  1021.         }
  1022.         if (FinishedSerRead()) {
  1023.             chars = IOsr.IOSer.io_Actual;
  1024.             chars += SerRead(&SerInBuf[chars], 256 - chars, 0);
  1025.             if (chars > 0) {
  1026.                 if (XPRFlags & XPRS_HOSTMON) {
  1027.                     chars = XProtocolHostMon(XIO, SerInBuf, chars, 256);
  1028.                 }
  1029.                 if (chars) {
  1030.                     Write(fileout, SerInBuf, chars);
  1031.                 }
  1032.             }
  1033.         }
  1034.         QueueCon();
  1035.         QueueSerRead(SerInBuf, 1);
  1036.     }
  1037.     if (Home) {
  1038.         UnLock(CurrentDir((struct FileLock *)Home));
  1039.     }
  1040.     if (OldFont) {
  1041.         (VOID)SetConFont(OldFont);
  1042.     }
  1043.     StdCon();
  1044.     AbortSerRead();
  1045.     AbortSerWrite();
  1046.     CloseProtocol();
  1047.     CloseStuff();
  1048. }
  1049.